import { IEvent } from '@xterm/xterm';

import { Deferred, Disposable, Event, IDisposable, Uri } from '../../utils';

import {
  ITerminalClient,
  ITerminalExitEvent,
  ITerminalExternalLinkProvider,
  ITerminalTitleChangeEvent,
} from './client';
import {
  IStartExtensionTerminalRequest,
  ITerminalLaunchError,
  ITerminalProcessExtHostProxy,
} from './extension';
import { ITerminalProfile } from './profile';
import {
  ICreateTerminalOptions,
  IShellLaunchConfig,
  ITerminalInfo,
  TerminalOptions,
} from './pty';
import { IWidget, IWidgetGroup } from './resize';
import { IContextKeyService } from '@opensumi/monaco-editor-core/esm/vs/platform/contextkey/common/contextkey';
import { IObservable } from '@opensumi/monaco-editor-core/esm/vs/base/common/observableInternal';

// 外部终端客户端接口
export interface ITerminalExternalClient {
  readonly id: string; // 终端 id
  readonly processId: Promise<number | undefined>; // 进程 id
  readonly name: string; // 终端名称
  show(preserveFocus?: boolean): void; // 显示终端
  hide(): void; // 隐藏终端
  dispose(): void; // 销毁终端
}

// 终端尺寸接口
export interface IBoundSize {
  width: number; // 宽度
  height: number; // 高度
}

// 创建终端客户端及 Widget 的参数
export interface ICreateClientWithWidgetOptions {
  terminalOptions: TerminalOptions; // 终端参数
  /**
   * 插件进程传递的唯一 ID
   */
  id?: string;
  /**
   * pty 进程退出后是否自动关闭 terminal 控件
   */
  closeWhenExited?: boolean;

  /**
   * 是否为 TaskExecutor
   */
  isTaskExecutor?: boolean;

  /**
   * 作为 TaskExecutor 时对应的 taskId
   */
  taskId?: string;

  /**
   * 自定义的参数，由上层集成方自行控制
   */
  args?: any;

  beforeCreate?: (terminalId: string) => void; // 创建前回调
}

// 终端过滤器
export interface TerminalCliterFilter {
  id?: string;
  name?: string;
  isTaskExecutor?: boolean;
}

// 终端控制器接口，负责终端的创建、管理、事件等
export interface ITerminalController extends Disposable {
  ready: Deferred<void>; // 控制器就绪
  focused: boolean; // 是否聚焦
  clients: Map<string, ITerminalClient>; // 所有终端客户端
  activeClient?: ITerminalClient; // 当前激活终端
  viewReady: Deferred<void>; // 视图就绪
  disposeTerminalClients(filter?: TerminalCliterFilter): void; // 销毁终端
  firstInitialize(): void; // 首次初始化
  recovery(history: ITerminalBrowserHistory): Promise<void>; // 恢复历史
  reconnect(): Promise<void>; // 重连
  focus(): void; // 聚焦
  blur(): void; // 失焦
  onContextMenu(e: React.MouseEvent<HTMLElement>): void; // 右键菜单
  findClientFromWidgetId(widgetId: string): ITerminalClient | undefined; // 通过 widgetId 查找终端
  createTerminalWithWidgetByTerminalOptions(
    options: ICreateClientWithWidgetOptions
  ): Promise<ITerminalClient>; // 创建终端（带 Widget）
  createTerminal(options: ICreateTerminalOptions): Promise<ITerminalClient>; // 创建终端
  createTerminalWithWidget(
    options: ICreateTerminalOptions
  ): Promise<ITerminalClient>; // 创建终端（带 Widget）
  clearCurrentGroup(): void; // 清空当前分组
  clearAllGroups(): void; // 清空所有分组
  showTerminalPanel(): void; // 显示终端面板
  hideTerminalPanel(): void; // 隐藏终端面板
  toggleTerminalPanel(): void; // 切换终端面板显示
  convertTerminalOptionsToLaunchConfig(
    options: TerminalOptions
  ): IShellLaunchConfig; // 转换参数
  convertProfileToLaunchConfig(
    shellLaunchConfigOrProfile:
      | IShellLaunchConfig
      | ITerminalProfile
      | undefined,
    cwd?: Uri | string
  ): IShellLaunchConfig;

  onDidOpenTerminal: Event<ITerminalInfo>; // 终端打开事件
  onDidCloseTerminal: Event<ITerminalExitEvent>; // 终端关闭事件
  onDidTerminalTitleChange: Event<ITerminalTitleChangeEvent>; // 终端标题变更事件
  onDidChangeActiveTerminal: Event<string>; // 活跃终端变更事件

  requestStartExtensionTerminal(
    proxy: ITerminalProcessExtHostProxy,
    cols: number,
    rows: number
  ): Promise<ITerminalLaunchError | undefined>; // 请求启动扩展终端
  readonly onInstanceRequestStartExtensionTerminal: Event<IStartExtensionTerminalRequest>; // 扩展终端启动请求事件
}

// 查找 UI 状态
export interface IUIState {
  isMatchCase: boolean; // 匹配大小写
  isWholeWord: boolean; // 全词匹配
  isUseRegexp: boolean; // 使用正则
}

// 查找结果
export interface ISearchResult {
  resultCount: number; // 匹配总数
  resultIndex: number; // 当前索引
}

// 终端查找服务接口
export interface ITerminalSearchService {
  isVisible: boolean; // 查找 UI 是否可见
  onVisibleChange: Event<boolean>; // 可见性变更事件
  UIState: IUIState; // UI 状态
  onResultChange: IEvent<ISearchResult> | undefined; // 查找结果变更事件

  text: string; // 查找文本

  open(): void; // 打开查找
  clear(): void; // 清除查找
  close(): void; // 关闭查找
  search(): void; // 执行查找
  searchNext(): void; // 查找下一个
  searchPrevious(): void; // 查找上一个
  updateUIState(state: Partial<IUIState>): void; // 更新 UI 状态
}

// 终端分组视图服务接口，负责终端分组和 Widget 管理
export interface ITerminalGroupViewService {
  readonly groups: IObservable<IWidgetGroup[]>; // 所有分组
  readonly currentGroupIndex: IObservable<number>; // 当前分组索引
  readonly currentGroup: IObservable<IWidgetGroup>; // 当前分组
  readonly currentGroupId: IObservable<string>; // 当前分组 id
  readonly currentWidgetId: IObservable<string>; // 当前 Widget id
  readonly currentWidget: IObservable<IWidget>; // 当前 Widget

  createGroup(): number; // 创建分组
  getGroup(index: number): IWidgetGroup; // 获取分组
  selectGroup(index: number): void; // 选中分组
  removeGroup(index: number): void; // 移除分组

  swapGroup(i: number, j: number): void; // 交换分组顺序

  createWidget(
    group: IWidgetGroup,
    id?: string,
    reuse?: boolean,
    isSimpleWidget?: boolean
  ): Promise<IWidget>; // 创建 Widget
  getWidget(id: string): IWidget; // 获取 Widget
  selectWidget(widgetId: string): void; // 选中 Widget
  removeWidget(id: string): void; // 移除 Widget

  onWidgetCreated: Event<IWidget>; // Widget 创建事件
  onWidgetSelected: Event<IWidget>; // Widget 选中事件
  onWidgetDisposed: Event<IWidget>; // Widget 销毁事件
  onWidgetEmpty: Event<void>; // Widget 为空事件

  empty(): boolean; // 是否为空
  clear(): void; // 清空所有分组和 Widget
}

// 终端浏览器历史结构
export interface ITerminalBrowserHistory {
  current: string | undefined; // 当前激活终端 id
  groups: { client: string; task?: string }[][]; // 分组及终端信息
}
